/**
 * MinimaxTree.java
 * @author J.T. Gralka <gralkajt@washjeff.edu>, Topher Witt <wittcm19@uww.edu>
 * @version 07/13/11
 *
 * Represents the Minimax tree structure.
 */

package exe.minimax;

import java.io.IOException;
import java.net.URI;
import java.util.HashMap;

import org.jdom.JDOMException;

import exe.pseudocode.*;

import exe.*;

public class MinimaxTree implements GAIGSdatastr {
	// ivars
	private static MinimaxNode root; // References the root node of the tree
	private static String name; // The name for the GAIGSdatastr
	private static ShowFile show; // References the ShowFile object
	private static boolean usesAlphaBeta; // Does this tree employ alpha-beta
											// pruning?
	static final String minFILE = "exe/minimax/minTemplate.xml";
	static final String maxFILE = "exe/minimax/maxTemplate.xml";
	static final String minimaxFILE = "exe/minimax/minimaxTemplate.xml";
	static final String minimaxABTemplate = "exe/minimax/minimaxABTemplate.xml";
	static final String abMaxFILE = "exe/minimax/maxABTemplate.xml";
	static final String abMinFILE = "exe/minimax/minABTemplate.xml";
	static PseudoCodeDisplay minPseudo, maxPseudo, minimaxPseudo,
			minimaxABPseudo, maxABPseudo, minABPseudo; // The pseudocode
	static String stackArray[] = { "", "", "", "", "", "", "", "", "", "" };// pseudocode
																			// call
																			// stack
	static int callIndex = 0;// increments and decrements along with the
								// recursions
	static GAIGSarray items; // the array of items

	// Constructors
	public MinimaxTree() {
		root = new MinimaxNode();
		name = "Minimax Search";
	}

	public MinimaxTree(String inputString) {
		MinimaxTreeParser parser = new MinimaxTreeParser(inputString);
		MinimaxTree tree = parser.getTree();
		root = tree.getRoot();
		name = "Minimax Search";
	}

	public MinimaxTree(MinimaxNode root) {
		this.root = root;
		name = "Minimax Search";
	}

	// Accessors
	/**
	 * Returns the root MinimaxNode of the Tree.
	 * 
	 * @return the root MinimaxNode of the tree
	 * @see MinimaxNode
	 */
	private MinimaxNode getRoot() {
		return root;
	}

	/**
	 * Returns the name of the GAIGSdatastr
	 * 
	 * @return the root MinimaxNode of the tree
	 */
	public String getName() {
		return name;
	}

	// Mutators
	public void setRoot(MinimaxNode root) {
		this.root = root;
	}

	public void setName(String name) {
		this.name = name;
	}

	private void setUsesAlphaBeta(boolean usesAlphaBeta) {
		this.usesAlphaBeta = usesAlphaBeta;
	}

	// Helper methods
	public void updateNodeTypes(boolean isMax) {
		root.setIsMax(isMax); // Set the root's type
		updateNodeTypes(root); // Traverse through the rest of the tree nodes
	}

	private void updateNodeTypes(MinimaxNode parent) {
		// For every child node of the parent...
		for (int i = 0; i < parent.getChildren().size(); i++) {
			MinimaxNode temp = parent.getChildren().get(i);
			temp.setIsMax(!parent.isMax()); // Toggle the node type
			if (!temp.isLeaf()) {// If the node is a not leaf...
				updateNodeTypes(temp); // Recurse for all of the subtrees
			}
		}
	}

	public MinimaxNode depthFirstSearch(MinimaxNode target) {
		return depthFirstSearch(root, target);
	}

	public MinimaxNode depthFirstSearch(MinimaxNode current, MinimaxNode target) {
		MinimaxNode rtn = new MinimaxNode();
		if (current == target)
			rtn = current;
		else {
			for (current = root; current.getNext() != null; current = current
					.getNext()) {
				return depthFirstSearch(current, target);
			}
		}
		return rtn;
	}

	// MINIMAX
	public MinimaxNode minimaxDecision(MinimaxNode node) {
		stackArray[0] = "minimaxDecision(treeRoot)\n";
		node.setIsVisited(true);
		node.setIsCurrent(true);
		int bestValue = -1;//make_minimax_uri(boolean isMax, int index, int bestValue, int line, int color
		try{ show.writeSnap("Is a max node?", docUri(), make_minimax_uri(node.isMax(), -1, bestValue, new int[] {1}, new int[] {PseudoCodeDisplay.RED}), this);	}catch(Exception e){e.printStackTrace();}
		if (node.isMax()) {
			bestValue = Integer.MIN_VALUE;
			try{ show.writeSnap("Yes.\nSet bestValue to negative infinity.", docUri(), make_minimax_uri(node.isMax(), -1, bestValue, new int[] {2}, new int[] {PseudoCodeDisplay.RED}), this); }catch(Exception e){e.printStackTrace();}
			//getMaxValue(node);
			try{ show.writeSnap("Explore each child.", docUri(), make_minimax_uri(node.isMax(), -1, bestValue, new int[] {3}, new int[] {PseudoCodeDisplay.RED}), this); }catch(Exception e){e.printStackTrace();}
			for (int i = 0; i < node.getChildren().size(); i++) {
				node.setIsCurrent(false);
				node.getChildren().get(i).setIsVisited(true);
				node.getChildren().get(i).setIsCurrent(true);
				try{ show.writeSnap("Call minValue(child).", docUri(), make_minimax_uri(node.isMax(), -1, bestValue, new int[] {4}, new int[] {PseudoCodeDisplay.RED}), this); }catch(Exception e){e.printStackTrace();}
				bestValue = Math.max(bestValue, getMinValue(node.getChildren().get(i)));
				try{ show.writeSnap("bestValue has been found.", docUri(), make_minimax_uri(node.isMax(), i, bestValue, new int[] {4}, new int[] {PseudoCodeDisplay.RED}), this); }catch(Exception e){e.printStackTrace();}
				node.getChildren().get(i).setIsCurrent(false);
				node.setIsCurrent(true);
				node.setValue(bestValue);
				try{ show.writeSnap("Root's utility is updated.", docUri(), make_minimax_uri(node.isMax(), i, bestValue, new int[] {4}, new int[] {PseudoCodeDisplay.RED}), this); }catch(Exception e){e.printStackTrace();}
				node.setIsCurrent(false);
			}
		} else {
			bestValue = Integer.MAX_VALUE;
			try{ show.writeSnap("No.\nSet bestValue to infinity.", docUri(), make_minimax_uri(node.isMax(), -1, bestValue, new int[] {5, 6}, new int[] {PseudoCodeDisplay.RED, PseudoCodeDisplay.RED}), this); }catch(Exception e){e.printStackTrace();}
			try{ show.writeSnap("Explore each child.", docUri(), make_minimax_uri(node.isMax(), -1, bestValue, new int[] {7}, new int[] {PseudoCodeDisplay.RED}), this); }catch(Exception e){e.printStackTrace();}
			for (int i = 0; i < node.getChildren().size(); i++) {
				node.setIsCurrent(false);
				node.getChildren().get(i).setIsVisited(true);
				node.getChildren().get(i).setIsCurrent(true);
				try{ show.writeSnap("Call maxValue(child).", docUri(), make_minimax_uri(node.isMax(), i, bestValue, new int[] {8}, new int[] {PseudoCodeDisplay.RED}), this); }catch(Exception e){e.printStackTrace();}
				bestValue = Math.min(bestValue, getMaxValue(node.getChildren().get(i)));
				try{ show.writeSnap("bestValue has been found.", docUri(), make_minimax_uri(node.isMax(), i, bestValue, new int[] {8}, new int[] {PseudoCodeDisplay.RED}), this); }catch(Exception e){e.printStackTrace();}
				node.getChildren().get(i).setIsCurrent(false);
				node.setIsCurrent(true);
				node.setValue(bestValue);
				try{ show.writeSnap("Root's utility is updated.", docUri(), make_minimax_uri(node.isMax(), i, bestValue, new int[] {4}, new int[] {PseudoCodeDisplay.RED}), this); }catch(Exception e){e.printStackTrace();}
				node.setIsCurrent(false);
			}
		}
		int i = 0;
		node.getChildren().get(i).setIsCurrent(true);
		try{ show.writeSnap("Initialize index to 0.\nFind best child.", docUri(), make_minimax_uri(node.isMax(), i, bestValue, new int[] {9, 10}, new int[] {PseudoCodeDisplay.RED, PseudoCodeDisplay.RED}), this); }catch(Exception e){e.printStackTrace();}
		while (i < node.getChildren().size()) {
			node.getChildren().get(i).setIsCurrent(true);
			try{ show.writeSnap("Does the child's utility equal the best value?", docUri(), make_minimax_uri(node.isMax(), i, bestValue, new int[] {11}, new int[] {PseudoCodeDisplay.RED}), this); }catch(Exception e){e.printStackTrace();}
			if (node.getChildren().get(i).getValue() == bestValue){
				try{ show.writeSnap("Yes. The child is found. Break from loop.", docUri(), make_minimax_uri(node.isMax(), i, bestValue, new int[] {12}, new int[] {PseudoCodeDisplay.RED}), this); }catch(Exception e){e.printStackTrace();}
				//node.getChildren().get(i).setIsCurrent(false);
				break;
			}
			i++;
			try{ show.writeSnap("No. Increment index and continue through loop.", docUri(), make_minimax_uri(node.isMax(), i, bestValue, new int[] {13}, new int[] {PseudoCodeDisplay.RED}), this); }catch(Exception e){e.printStackTrace();}
			node.getChildren().get(i-1).setIsCurrent(false);
		}
		node.setIsCurrent(true);
		node.getChildren().get(i).setIsCurrent(false);
		node.getChildren().get(i).setIsPath(true);
		try{ show.writeSnap("Return that child.", docUri(), make_minimax_uri(node.isMax(), i, bestValue, new int[] {14}, new int[] {PseudoCodeDisplay.RED}), this); }catch(Exception e){e.printStackTrace();}
		return node.getChildren().get(i);
	}

	//make_minORmax_uri(boolean isMax, int A, int B, int V, int childIndex, int line, int color)
	public int getMaxValue(MinimaxNode node) {
		stackArray[(callIndex += 1) + 1] = spacePad() + "maxValue(node)\n";
		node.setIsVisited(true);
		//node.setIsCurrent(true);
		int maxValue = Integer.MIN_VALUE; // Value is set to negative "infinity"
		try{ show.writeSnap("Is it a leaf node?", docUri(), make_minORmax_uri(node.isMax(), -1, -1, -1, -1, new int[] {1}, new int[] {PseudoCodeDisplay.RED}), this);	}catch(Exception e){e.printStackTrace();}
		if (node.isLeaf()){
			stackArray[(callIndex -= 1) + 2] = "";
			try{ show.writeSnap("Yes. Return node.utility.", docUri(), make_minORmax_uri(node.isMax(), -1, -1, -1, -1, new int[] {2}, new int[] {PseudoCodeDisplay.RED}), this);	}catch(Exception e){e.printStackTrace();}
			return node.getValue();
		}else
			try{ show.writeSnap("No. Initialize node.utility to negative infinity.\nLook at each child.", docUri(), make_minORmax_uri(node.isMax(), -1, -1, maxValue, -1, new int[] {3, 4}, new int[] {PseudoCodeDisplay.RED, PseudoCodeDisplay.RED}), this);	}catch(Exception e){e.printStackTrace();}
			for (int i = 0; i < node.getChildren().size(); i++) {
				int oldV = maxValue;
				node.getChildren().get(i).setIsCurrent(true);
				node.setIsCurrent(false);
				try{ show.writeSnap("Call minValue() for the "+ordinalSuffix(i+1)+" child.", docUri(), make_minORmax_uri(node.isMax(), -1, -1, node.getValue(), i, new int[] {5}, new int[] {PseudoCodeDisplay.RED}), this);	}catch(Exception e){e.printStackTrace();}
				maxValue = Math.max(maxValue, getMinValue(node.getChildren().get(i)));
				node.getChildren().get(i).setIsCurrent(false);
				node.setIsCurrent(true);
				node.setValue(maxValue);
				if(maxValue != oldV)
					try{ show.writeSnap("The parent's utility is updated from "+returnInfinity(oldV)+" to "+returnInfinity(maxValue), docUri(), make_minORmax_uri(node.isMax(), -1, -1, node.getValue(), i, new int[] {6}, new int[] {PseudoCodeDisplay.RED}), this);	}catch(Exception e){e.printStackTrace();}
				else
					try{ show.writeSnap("The parent's utility does not change.", docUri(), make_minORmax_uri(node.isMax(), -1, -1, node.getValue(), i, new int[] {5}, new int[] {PseudoCodeDisplay.RED}), this);	}catch(Exception e){e.printStackTrace();}
			}
		node.setValue(maxValue);
		stackArray[(callIndex -= 1) + 2] = "";
		//try{ show.writeSnap("The parent's utility is updated to: "+maxValue+".", docUri(), make_minORmax_uri(node.isMax(), -1, -1, node.getValue(), -1, new int[] {6}, new int[] {PseudoCodeDisplay.RED}), this);	}catch(Exception e){e.printStackTrace();}
		return maxValue;
	}

	public int getMinValue(MinimaxNode node) {
		stackArray[(callIndex += 1) + 1] = spacePad() + "minValue(node)\n";
		node.setIsVisited(true);
		//node.setIsCurrent(false);
		int minValue = Integer.MAX_VALUE;
		try{ show.writeSnap("Is it a leaf node?", docUri(), make_minORmax_uri(node.isMax(), -1, -1, -1, -1, new int[] {1}, new int[] {PseudoCodeDisplay.RED}), this);	}catch(Exception e){e.printStackTrace();}
		if (node.isLeaf()){
			stackArray[(callIndex -= 1) + 2] = "";
			try{ show.writeSnap("Yes. Return node.utility.", docUri(), make_minORmax_uri(node.isMax(), -1, -1, -1, -1, new int[] {2}, new int[] {PseudoCodeDisplay.RED}), this);	}catch(Exception e){e.printStackTrace();}
			return node.getValue();
		}else
			try{ show.writeSnap("No. Initialize node.utility to infinity.\nLook at each child.", docUri(), make_minORmax_uri(node.isMax(), -1, -1, minValue, -1, new int[] {3, 4}, new int[] {PseudoCodeDisplay.RED, PseudoCodeDisplay.RED}), this);	}catch(Exception e){e.printStackTrace();}
			for (int i = 0; i < node.getChildren().size(); i++) {
				int oldV = minValue;
				node.getChildren().get(i).setIsCurrent(true);
				node.setIsCurrent(false);
				try{ show.writeSnap("Call maxValue() for the "+ordinalSuffix(i+1)+" child.", docUri(), make_minORmax_uri(node.isMax(), -1, -1, node.getValue(), i, new int[] {5}, new int[] {PseudoCodeDisplay.RED}), this);	}catch(Exception e){e.printStackTrace();}
				minValue = Math.min(minValue, getMaxValue(node.getChildren().get(i)));
				node.getChildren().get(i).setIsCurrent(false);
				node.setIsCurrent(true);
				node.setValue(minValue);
				if(minValue != oldV)
					try{ show.writeSnap("The parent's utility is updated from "+returnInfinity(oldV)+" to "+returnInfinity(minValue), docUri(), make_minORmax_uri(node.isMax(), -1, -1, node.getValue(), i, new int[] {6}, new int[] {PseudoCodeDisplay.RED}), this);	}catch(Exception e){e.printStackTrace();}
				else
					try{ show.writeSnap("The parent's utility does not change.", docUri(), make_minORmax_uri(node.isMax(), -1, -1, node.getValue(), i, new int[] {5}, new int[] {PseudoCodeDisplay.RED}), this);	}catch(Exception e){e.printStackTrace();}
			}
		node.setValue(minValue);
		stackArray[(callIndex -= 1) + 2] = "";
		//try{ show.writeSnap("The parent's utility is updated to: "+minValue+".", docUri(), make_minORmax_uri(node.isMax(), -1, -1, node.getValue(), -1, new int[] {6}, new int[] {PseudoCodeDisplay.RED}), this);	}catch(Exception e){e.printStackTrace();}
		return minValue;
	}

	// ALPHA-BETA PRUNING
	private MinimaxNode alphaBetaDecision(MinimaxNode node, int alpha, int beta) {
		int j = 0;
		if (node.isMax()) {
			for (int i = 0; i < node.getChildren().size(); i++) {
				alpha = Math.max(alpha,
						getMinValue(node.getChildren().get(i), alpha, beta));
			}
			while (j < node.getChildren().size()) {
				if (node.getChildren().get(j).getValue() == alpha){
					break;
				}
				j++;
			}
				
		} else {
			for (int i = 0; i < node.getChildren().size(); i++) {
				beta = Math.min(beta,
						getMaxValue(node.getChildren().get(i), alpha, beta));
			}
			while (j < node.getChildren().size()) {
				if (node.getChildren().get(j).getValue() == beta){
					break;
				}
				j++;
			}
		}
		return node.getChildren().get(j);
	}

	private int getMaxValue(MinimaxNode node, int alpha, int beta) {
		if (node.isLeaf())
			return node.getValue();
		for (int i = 0; i < node.getChildren().size(); i++) {
			alpha = Math.max(alpha,
					getMinValue(node.getChildren().get(i), alpha, beta));
			if (alpha >= beta)
				return beta;
		}
		node.setValue(alpha);
		return alpha;
	}

	private int getMinValue(MinimaxNode node, int alpha, int beta) {
		if (node.isLeaf())
			return node.getValue();
		for (int i = 0; i < node.getChildren().size(); i++) {
			beta = Math.min(beta,
					getMaxValue(node.getChildren().get(i), alpha, beta));
			if (beta <= alpha)
				return alpha;
		}
		node.setValue(beta);
		return beta;
	}


	// /////////////////////////////////PSEUDOCODE////////////////////////////////////////////////////////////////////////////////////////
	// all your code are belong to us
	// Method creates pseudocode for both the getMinValue() and getMaxValue()
	// methods
	private static String make_minORmax_uri(boolean isMax, int A, int B, int V, int childIndex, int line, int color) {
		return make_minORmax_uri(isMax, A, B, V, childIndex,
				new int[] { line }, new int[] { color });
	}

	private static String make_minORmax_uri(boolean isMax, int A, int B, int V, int childIndex, int[] lines, int[] colors) {
		// isMax indicates whether its for getMaxValue() or getMinValue()
		String indexVal = childIndex == -1 ? "?" : String.valueOf(childIndex);
		String aVal = A == -1 ? "?" : returnInfinity(A);
		String bVal = B == -1 ? "?" : returnInfinity(B);
		String vVal = V == -1 ? "?" : returnInfinity(V);

		HashMap<String, String> map = new HashMap<String, String>();

		map.put("i", indexVal);
		map.put("V", vVal);
		map.put("s", getStack());

		String uri = null;
		try {
			if (usesAlphaBeta) {// is Alpha Beta
				if (isMax) {
					map.put("A", aVal);
					map.put("B", bVal);
					uri = maxABPseudo.pseudo_uri(map, lines, colors);
				} else {
					map.put("A", aVal);
					map.put("B", bVal);
					uri = minABPseudo.pseudo_uri(map, lines, colors);
				}
			} else {// not Alpha Beta
				if (isMax)
					uri = maxPseudo.pseudo_uri(map, lines, colors);
				else
					uri = minPseudo.pseudo_uri(map, lines, colors);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return uri;
	}

	// Method creates the pseudocode for the minimaxDecision() method
	private static String make_minimax_uri(boolean isMax, int index, int bestValue, int line,
			int color) {
		// NOTE: isMax=0=(not yet declared) isMax=-1=false isMax=+1=true
		return make_minimax_uri(isMax, index, bestValue, new int[] { line },
				new int[] { color });
	}

	private static String make_minimax_uri(boolean isMax, int index, int bestValue, int[] lines, int[] colors) {
		HashMap<String, String> map = new HashMap<String, String>();
		String max = isMax + "";
		String dex = index == -1 ? "?" : returnInfinity(index);
		String util = bestValue == -1 ? "?" : returnInfinity(bestValue);
		map.put("m", max);
		map.put("i", dex);
		map.put("V", util);
		map.put("s", getStack());

		String uri = null;
		try {
			uri = minimaxPseudo.pseudo_uri(map, lines, colors);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return uri;
	}

	// Method creates the pseudocode for the alphaBetaSearch() method
	private static String make_minimaxAB_uri(boolean isMax, int value, int childUtil, int index, int line, int color) {
		return make_minimaxAB_uri(isMax, value, childUtil, index,
				new int[] { line }, new int[] { color });
	}

	private static String make_minimaxAB_uri(boolean isMax, int value, int childUtil, int index, int[] lines, int[] colors) {
		HashMap<String, String> map = new HashMap<String, String>();
		String val = value == -1 ? "?" : returnInfinity(value);
		String in = index == -1 ? "?" : returnInfinity(index);
		String ch = childUtil == -1 ? "?" : returnInfinity(childUtil);
		map.put("V", val);
		map.put("i", in);
		map.put("c", ch);
		map.put("s", getStack());

		String uri = null;
		try {
			uri = minimaxABPseudo.pseudo_uri(map, lines, colors);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return uri;
	}

	// Return an appropriate inline string for the info page
	private static String docUri() {
		String content = "";
		if (usesAlphaBeta)
			content = "<html><head><title>Minimax with Alpha Beta Pruning</title></head><body><h1>Minimax with Alpha Beta Pruning</h1>The infamous minimax algorithm with Alpha Beta Pruning</body></html>";
		else
			content = "<html><head><title>Minimax</title></head><body><h1>Minimax</h1>The infamous minimax algorithm</body></html>";

		URI uri = null;
		try {
			uri = new URI("str", content, "");
		} catch (java.net.URISyntaxException e) {
		}
		return uri.toASCIIString();
	}

	private static String getStack() {
		String stack = "";
		for (int index = 0; index < 10; index++) {
			stack += stackArray[index];
		}
		return stack;
	}

	private static String spacePad() {
		String pad = "";
		for (int index = 0; index < callIndex; index++) {
			pad += "  ";
		}
		return pad;
	}

	private static String ordinalSuffix(int num) {
		String str = "" + num;
		if (str.length() >= 2) {
			int penultimate = Integer.parseInt(str.substring(str.length() - 2,
					str.length()));
			if (penultimate > 9 && penultimate < 21)
				return num + "th";
		}

		int last = Integer.parseInt("" + str.charAt(str.length() - 1));
		switch (last) {
		case 1:
			return num + "st";
		case 2:
			return num + "nd";
		case 3:
			return num + "rd";
		case 4:
		case 5:
		case 6:
		case 7:
		case 8:
		case 9:
		default:
			return num + "th";
		}
	}

	public void addChild(MinimaxNode parent, MinimaxNode newChild) {
		parent.getChildren().add(newChild);
	}

	public static String returnInfinity(int v) {
		String value = "";
		if (v == Integer.MAX_VALUE)
			value = "~";// (char)236+"";//(char)8734+"";
		else if (v == Integer.MIN_VALUE)
			value = "-~";// "-"+(char)236;//"-"+(char)8734;
		else
			value = v + "";
		return value;
	}

	// /////////////////////////////////////////////////////XML//////////////////////////////////////////////////////////////////////
	public String toXML() {
		String str = "<minimax_tree" +
		// If the tree uses alpha beta pruning, indicate so in the XML.
				(usesAlphaBeta ? " alphaBeta=\"true\">\n" : ">\n");
		str += writeNodeXML(root);
		str += "</minimax_tree>\n";
		return str;
	}

	private String writeNodeXML(MinimaxNode node) {
		String str = "<node isMax=\"" + (node.isMax() ? "true\"" : "false\"");

		if (usesAlphaBeta)
			str += " alpha = \"" + node.getAlpha() + "\"" + " beta = \""
					+ node.getBeta() + "\"" + " isPruned = \""
					+ node.isPruned() + "\"";

		str += (node.isVisited() ? " isVisited=\"true\"" : "")
				+ (node.isCurrent() ? " isCurrent=\"true\"" : "") +
				 (node.isPath()?" isPath=\"true\"":"") +
				(node.isUtilitySet() ? " utility=\"" + node.getValue() + "\""
						: "");

		if (node.isLeaf()) {
			str += "/>\n";
			return str;
		}

		str += ">\n";

		for (int i = 0; i < node.getChildren().size(); i++) {
			str += writeNodeXML(node.getChildren().get(i));
		}

		if (!node.isLeaf())
			str += "</node>\n";

		return str;
	}

	// Main method
	public static void main(String[] args) {
		try {
			show = new ShowFile("test.sho");
		} catch (Exception e) {
			e.printStackTrace();
		}

		try {
			minPseudo = new PseudoCodeDisplay(minFILE);
			maxPseudo = new PseudoCodeDisplay(maxFILE);
			minimaxPseudo = new PseudoCodeDisplay(minimaxFILE);
			minimaxABPseudo = new PseudoCodeDisplay(minimaxABTemplate);
			maxABPseudo = new PseudoCodeDisplay(abMaxFILE);
			minABPseudo = new PseudoCodeDisplay(abMinFILE);
		} catch (JDOMException e1) {
			e1.printStackTrace();
		} catch (IOException e1) {
			e1.printStackTrace();
		}

		MinimaxTree tree = new MinimaxTree(
				"#3#2#2#2$7$2#1$4#2#2$4$9#3$2$1$1#1#3#1$6#1$4#1$7#1#1#2$1$6");
		//tree.minimaxDecision(tree.getRoot());
		tree.setUsesAlphaBeta(true);
		System.out.println(tree.alphaBetaDecision(tree.getRoot(),
				Integer.MIN_VALUE, Integer.MAX_VALUE).getValue());
		
		//System.out.println(tree.alphaBetaDecision(tree.getRoot(), Integer.MAX_VALUE, Integer.MIN_VALUE).getValue());
		show.close();
	}
}